//
// a Client to request file from server
// connection: OBEX
//

import java.io.*;
import javax.bluetooth.*;
import javax.obex.*;
import javax.microedition.io.*;

public class OBEXClient implements DiscoveryListener
{
  public static void main(String args[]) throws BluetoothStateException
  {
    LocalDevice localdev = null;
    OBEXClient listener = new OBEXClient();

    try {
      localdev = LocalDevice.getLocalDevice();
    } catch (BluetoothStateException e) {
      System.out.println("ERROR: cannot access local device");
      System.exit(1);
    }

    DiscoveryAgent agent = localdev.getDiscoveryAgent();
    try {
      agent.startInquiry(DiscoveryAgent.GIAC, listener);
    } catch (BluetoothStateException e) {
      System.out.println("ERROR: device inquiry failed");
      System.exit(2);
    }

    // pause for a while
    // NOTE: if there is no remote device, this may go into infinite loop
    // this program also shows that to start services from a client it's
    // better to have a GUI interface.
    while (remote == null)
      try {
        Thread.sleep(5000);
      } catch (Exception e) {}

    UUID[] uuidSet = new UUID[1];
    uuidSet[0] = new UUID("102030405060708090A0B0C0D0E0F011", false);

    int trans;
    try {
      trans = agent.searchServices(null, uuidSet, remote, listener);
    } catch (BluetoothStateException e) {
      System.out.println("device unable to begin service inquiry");
    }
  }

  // implement required listener methods.
  private static RemoteDevice remote = null;
  private static ServiceRecord first = null;

  public void deviceDiscovered(RemoteDevice rt, DeviceClass cod) {
    remote = rt;
    System.out.println("A Remote Device Found:");
    System.out.println("Address: " + rt.getBluetoothAddress());
    try {
      System.out.println("   Name: " + rt.getFriendlyName(true));
    } catch (IOException e) {}
  }

  public void inquiryCompleted(int distype) {
    if(distype == INQUIRY_TERMINATED)
      System.out.println("Application Terminated");
    else if(distype == INQUIRY_COMPLETED)
      System.out.println("Inquiry Completed");
    else
      System.out.println("ERROR: Inquiry aborted");
  }

  public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
    first = servRecord[0];

    String url = first.getConnectionURL(first.NOAUTHENTICATE_NOENCRYPT, false);
    try {
      ClientSession conn = (ClientSession) Connector.open(url);

      // check to see if OBEX connection is successful
      HeaderSet reshead = conn.connect(null);
      int status = reshead.getResponseCode();
      if(status != ResponseCodes.OBEX_HTTP_OK) {
        System.out.println("OBEX connection error!!");
        System.exit(1);
      }

      System.out.println("Getting object from server");

      // get object from server
      HeaderSet headset = conn.createHeaderSet();
      headset.setHeader(HeaderSet.NAME, "test.xml");
      Operation op = conn.get(headset);
      InputStream is = op.openInputStream();
      ByteArrayOutputStream os = new ByteArrayOutputStream();

      System.out.println("Reading data from server");

      // read data from server
      int data;
      while((data = is.read()) != -1)
        os.write((byte) data);
      System.out.println("Size: " + os.size());
      System.out.println(os.toString());

      // Although this is not necessary required, but if this is not inserted,
      // I got IO error. And this type of IO error requires some hardware
      // reset.
      Thread.sleep(5000);

      is.close();
      os.close();
      conn.close();
    } catch (Exception e) {
      System.out.println("ERROR: connection error");
    }
  }

  public void serviceSearchCompleted(int transID, int respCode) {
    if(respCode == SERVICE_SEARCH_COMPLETED)
      System.out.println("Services successfully located");
    else if(respCode == SERVICE_SEARCH_TERMINATED)
      System.out.println("Service inquiry was cancelled");
    else if(respCode == SERVICE_SEARCH_DEVICE_NOT_REACHABLE)
      System.out.println("Service connection cannot be established");
    else if(respCode == SERVICE_SEARCH_NO_RECORDS)
      System.out.println("No service found");
    else
      System.out.println("ERROR: service inquiry failed");
  }
}